home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue55 / System / RASControls.pas
Pascal/Delphi Source File  |  2000-02-09  |  16KB  |  439 lines

  1. unit RASControls;
  2.  
  3. interface
  4.  
  5. uses
  6.     Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
  7.  
  8. type
  9.     TRasDialParams = record
  10.     dwSize: Integer;
  11.     EntryName: array [0..256] of Char;
  12.     PhoneNumber: array [0..128] of Char;
  13.     CallbackNumber: array [0..128] of Char;
  14.     UserName: array [0..256] of Char;
  15.     Password: array [0..256] of Char;
  16.     Domain: array [0..15] of Char;
  17.     end;
  18.  
  19.     TRasDialParamsNT4_2000 = record
  20.     dwSize: Integer;
  21.     EntryName: array [0..256] of Char;
  22.     PhoneNumber: array [0..128] of Char;
  23.     CallbackNumber: array [0..128] of Char;
  24.     UserName: array [0..256] of Char;
  25.     Password: array [0..256] of Char;
  26.     Domain: array [0..15] of Char;
  27.         SubEntry: Integer;
  28.         CallbackId: Integer;
  29.     end;
  30.  
  31.     TRasEntry = record
  32.     dwSize, Options: Integer;                                                     // General stuff
  33.     CountryID, CountryCode: Integer;                                              // Phone/Country info
  34.     AreaCode: array [0..10] of Char;
  35.     LocalPhoneNumber: array [0..128] of Char;
  36.     AlternateOffset: Integer;
  37.     ipaddr, ipaddrDns, ipaddrDnsAlt, ipaddrWins, ipaddrWinsAlt: Integer;          // PPP/Ip
  38.     FrameSize, NetProtocols, FramingProtocol: Integer;                            // Framing
  39.     Script: array [0..Max_Path - 1] of Char;                                      // Scripting
  40.     AutodialDll: array [0..Max_Path - 1] of Char;                                 // AutoDial
  41.     AutodialFunc: array [0..Max_Path - 1] of Char;
  42.     DeviceType: array [0..16] of Char;                                            // Device
  43.     DeviceName: array [0..128] of Char;
  44.     X25PadType: array [0..32] of Char;                                            // X.25
  45.     X25Address: array [0..200] of Char;
  46.     X25Facilities: array [0..200] of Char;
  47.     X25UserData: array [0..200] of Char;
  48.     Channels: Integer;
  49.     Reserved1, Reserved2: Integer;
  50.     end;
  51.  
  52.     TRASBaseComponent = class (TComponent)
  53.     private
  54.         { Private declarations }
  55.         fErrorText: String;
  56.         fError: Integer;
  57.         fOnError: TNotifyEvent;
  58.         fRasLib, fRasExtensionsLib: THandle;
  59.         fWin2000, fWinNT4, fAvailable, fDummy1: Boolean;
  60.         function GetProc (ProcName: PChar): Pointer;
  61.         function CallProc (Err: Integer): Boolean;
  62.     public
  63.         { Public declarations }
  64.         constructor Create (AOwner: TComponent); override;
  65.         destructor Destroy; override;
  66.         property ErrorText: String read fErrorText;
  67.         property Error: Integer read fError;
  68.     published
  69.         { Published declarations }
  70.         property Available: Boolean read fAvailable write fDummy1 stored False;
  71.         property OnError: TNotifyEvent read fOnError write fOnError;
  72.     end;
  73.  
  74.     TRASPhoneBookManager = class (TRASBaseComponent)
  75.     private
  76.         { Private declarations }
  77.         fItemIndex: Integer;
  78.         fEntries, fDummy2: TStrings;
  79.         fPhoneBookFileName, fDummy3: String;
  80.         procedure SetItemIndex (Value: Integer);
  81.         function PhoneBookNameAsPChar: PChar;
  82.         procedure SetPhoneBookFileName (const Value: String);
  83.         function GetDialParameters (Index: Integer): String;
  84.         function GetEntryProperties (Index: Integer): String;
  85.         function InternalGetDialParameters (var Dest: TRasDialParamsNT4_2000; var GotPassword: Bool): Integer;
  86.         function InternalGetEntryProperties (var Dest: TRASEntry): Boolean;
  87.     protected
  88.         { Protected declarations }
  89.     public
  90.         { Public declarations }
  91.         constructor Create (AOwner: TComponent); override;
  92.         destructor Destroy; override;
  93.         function Add: Boolean;
  94.         function Delete: Boolean;
  95.         function Edit: Boolean;
  96.         function Rename (const NewName: String): Boolean;
  97.         function ValidateEntryName (const EntryName: String): Boolean;
  98.         procedure Refresh;
  99.     published
  100.         { Published declarations }
  101.         property ItemIndex: Integer read fItemIndex write SetItemIndex stored False;
  102.         property PhoneBookFileName: String read fPhoneBookFileName write SetPhoneBookFileName;
  103.         property Entries: TStrings read fEntries write fDummy2 stored False;
  104.         property UserName: String index 0 read GetDialParameters write fDummy3 stored False;
  105.         property Password: String index 1 read GetDialParameters write fDummy3 stored False;
  106.         property PhoneNumber: String index 0 read GetEntryProperties write fDummy3 stored False;
  107.         property DeviceType: String index 1 read GetEntryProperties write fDummy3 stored False;
  108.         property DeviceName: String index 2 read GetEntryProperties write fDummy3 stored False;
  109.     end;
  110.  
  111. procedure Register;
  112.  
  113. implementation
  114.  
  115. // TRASBaseComponent
  116.  
  117. constructor TRASBaseComponent.Create (AOwner: TComponent);
  118. begin
  119.     Inherited Create (AOwner);
  120.     fRasLib := LoadLibrary ('rasapi32.dll');
  121.     fRasExtensionsLib := LoadLibrary ('rnaph.dll');
  122.     fAvailable := fRasLib <> 0;
  123.     fWin2000 := (Win32Platform = Ver_Platform_Win32_NT) and (Win32MajorVersion >= 5);
  124.     fWinNT4 := (Win32Platform = Ver_Platform_Win32_NT) and (Win32MajorVersion = 4);
  125. end;
  126.  
  127. destructor TRASBaseComponent.Destroy;
  128. begin
  129.     if fRasLib <> 0 then FreeLibrary (fRasLib);
  130.     if fRasExtensionsLib <> 0 then FreeLibrary (fRasExtensionsLib);
  131.     Inherited;
  132. end;
  133.  
  134. function TRASBaseComponent.GetProc (ProcName: PChar): Pointer;
  135. begin
  136.     Result := Nil;
  137.     if fAvailable then begin
  138.         Result := GetProcAddress (fRasLib, ProcName);
  139.         if (Result = Nil) and (fRasExtensionsLib <> 0) then
  140.             Result := GetProcAddress (fRasExtensionsLib, ProcName);
  141.     end;
  142. end;
  143.  
  144. function TRASBaseComponent.CallProc (Err: Integer): Boolean;
  145. var
  146.     szErr: array [0..1024] of Char;
  147.     RasGetErrorString: function (Err: Integer; Buff: PChar; BuffSize: Integer): Integer; stdcall;
  148. begin
  149.     fError := Err;  Result := Err = 0;
  150.     if Result then fErrorText := '' else begin
  151.        RasGetErrorString := GetProc ('RasGetErrorStringA');
  152.        if RasGetErrorString (Err, szErr, sizeof (szErr)) = 0 then fErrorText := szErr else begin
  153.            fErrorText := SysErrorMessage (Err);
  154.            if fErrorText = '' then fErrorText := Format ('Unknown error (%d)', [Err]);
  155.        end;
  156.  
  157.        fErrorText := 'RAS: ' + fErrorText;
  158.        if Assigned (fOnError) then fOnError (Self);
  159.     end;
  160. end;
  161.  
  162. // TRASPhoneBook
  163.  
  164. constructor TRASPhoneBookManager.Create (AOwner: TComponent);
  165. begin
  166.     Inherited Create (AOwner);
  167.     fEntries := TStringList.Create;
  168.     Refresh;
  169. end;
  170.  
  171. destructor TRASPhoneBookManager.Destroy;
  172. begin
  173.     fEntries.Free;
  174.     Inherited;
  175. end;
  176.  
  177. procedure TRASPhoneBookManager.SetPhoneBookFileName (const Value: String);
  178. begin
  179.     if (fPhoneBookFileName <> Value) and FileExists (Value) then begin
  180.         fPhoneBookFileName := Value;
  181.         Refresh;
  182.     end;
  183. end;
  184.  
  185. function TRASPhoneBookManager.PhoneBookNameAsPChar: PChar;
  186. begin
  187.     if fPhoneBookFileName = '' then
  188.         Result := Nil else Result := PChar (fPhoneBookFileName);
  189. end;
  190.  
  191. procedure TRASPhoneBookManager.Refresh;
  192. type
  193.     TRasEntryName = record
  194.         dwSize: Integer;
  195.     szEntryName: array [0..257] of Char;
  196.     end;
  197.  
  198.     TRasEntryName2000 = record
  199.         dwSize: Integer;
  200.     szEntryName: array [0..257] of Char;
  201.         dwFlags: Integer;
  202.         szPhonebookPath: array [0..Max_Path] of Char;
  203.     end;
  204. var
  205.     CurEntry, Buffer: PChar;
  206.     Idx, BufSize, NumEntries, EntrySize: Integer;
  207.     RasEnumEntries: function (Reserved, Phonebook, Buffer: PChar;
  208.                               var BufSize, NumEntries: Integer): Integer; stdcall;
  209. begin
  210.     if fAvailable then begin
  211.         // First off, refresh the entries list
  212.         fEntries.Clear;
  213.         RasEnumEntries := GetProc ('RasEnumEntriesA');
  214.         EntrySize := sizeof (TRasEntryName);
  215.         if fWin2000 then EntrySize := sizeof (TRasEntryName2000);
  216.  
  217.         // Make a dummy call to get the wanted buffer size
  218.         Idx := EntrySize; BufSize := sizeof (Idx);
  219.         RasEnumEntries (Nil, PhoneBookNameAsPChar, @Idx, BufSize, NumEntries);
  220.  
  221.         // Now do it for real
  222.         Buffer := AllocMem (BufSize);
  223.         try
  224.            PInteger (Buffer)^ := EntrySize;
  225.            if CallProc (RasEnumEntries (Nil, PhoneBookNameAsPChar, Buffer, BufSize, NumEntries)) then begin
  226.                CurEntry := Buffer;
  227.                 for Idx := 0 to NumEntries - 1 do begin
  228.                     fEntries.Add (CurEntry + sizeof (Integer));
  229.                     Inc (CurEntry, EntrySize);
  230.                 end;
  231.             end;
  232.         finally
  233.             FreeMem (Buffer);
  234.             if fEntries.Count > 0 then fItemIndex := 0 else fItemIndex := -1;
  235.         end;
  236.     end;
  237. end;
  238.  
  239. procedure TRASPhoneBookManager.SetItemIndex (Value: Integer);
  240. begin
  241.     if (Value >= 0) and (Value < fEntries.Count) and (fEntries.Count > 0) then fItemIndex := Value;
  242. end;
  243.  
  244. function TRASPhoneBookManager.Add: Boolean;
  245. var
  246.     RasCreatePhoneBookEntry: function (WndParent: hWnd; Phonebook: PChar): Integer; stdcall;
  247. begin
  248.     Result := False;
  249.     if fAvailable then begin
  250.        RasCreatePhoneBookEntry := GetProc ('RasCreatePhonebookEntryA');
  251.        if Assigned (RasCreatePhoneBookEntry) then
  252.            Result := CallProc (RasCreatePhoneBookEntry (Application.Handle, PhoneBookNameAsPChar));
  253.        if Result then Refresh;
  254.     end;
  255. end;
  256.  
  257. function TRASPhoneBookManager.Delete: Boolean;
  258. var
  259.     RasDeleteEntry: function (Phonebook, EntryName: PChar): Integer; stdcall;
  260. begin
  261.     Result := False;
  262.     if fAvailable and (fItemIndex >= 0) then begin
  263.        RasDeleteEntry := GetProc ('RasDeleteEntryA');
  264.        if Assigned (RasDeleteEntry) then Result := CallProc (RasDeleteEntry (PhoneBookNameAsPChar, PChar (fEntries [fItemIndex])));
  265.        if Result then Refresh;
  266.     end;
  267. end;
  268.  
  269. function TRASPhoneBookManager.Edit: Boolean;
  270. var
  271.     RasEditPhonebookEntry: function (WndParent: hWnd; Phonebook, EntryName: PChar): Integer; stdcall;
  272. begin
  273.     Result := False;
  274.     if fAvailable and (fItemIndex >= 0) then begin
  275.        RasEditPhonebookEntry := GetProc ('RasEditPhonebookEntryA');
  276.        if Assigned (RasEditPhonebookEntry) then
  277.            Result := CallProc (RasEditPhonebookEntry (Application.Handle, PhoneBookNameAsPChar, PChar (fEntries [fItemIndex])));
  278.        if Result then Refresh;
  279.     end;
  280. end;
  281.  
  282. function TRASPhoneBookManager.ValidateEntryName (const EntryName: String): Boolean;
  283. var
  284.     RasValidateEntryName: function (Phonebook, EntryName: PChar): Integer; stdcall;
  285. begin
  286.     Result := False;
  287.     if fAvailable then begin
  288.        RasValidateEntryName := GetProc ('RasValidateEntryNameA');
  289.        if Assigned (RasValidateEntryName) then Result := CallProc (RasValidateEntryName (PhoneBookNameAsPChar, PChar (EntryName)));
  290.     end;
  291. end;
  292.  
  293. function TRASPhoneBookManager.Rename (const NewName: String): Boolean;
  294. var
  295.     RasRenameEntry: function (Phonebook, OldName, NewName: PChar): Integer; stdcall;
  296. begin
  297.     Result := False;
  298.     if fAvailable and (fItemIndex >= 0) and ValidateEntryName (NewName) then begin
  299.        RasRenameEntry := GetProc ('RasRenameEntryA');
  300.        if Assigned (RasRenameEntry) then
  301.            Result := CallProc (RasRenameEntry (PhoneBookNameAsPChar, PChar (fEntries [fItemIndex]), PChar (NewName)));
  302.        if Result then Refresh;
  303.     end;
  304. end;
  305.  
  306. function TRASPhoneBookManager.InternalGetDialParameters (var Dest: TRasDialParamsNT4_2000; var GotPassword: Bool): Integer;
  307. var
  308.     RasGetEntryDialParams: function (Phonebook: PChar; var RasDialParams: TRasDialParamsNT4_2000; var GotPassword: Bool): Integer; stdcall;
  309. begin
  310.     Result := 0;
  311.     if fAvailable and (fItemIndex >= 0) then begin
  312.         RasGetEntryDialParams := GetProc ('RasGetEntryDialParamsA');
  313.         if Assigned (RasGetEntryDialParams) then begin
  314.             if fWin2000 or fWinNT4 then Dest.dwSize := sizeof (TRasDialParamsNT4_2000)
  315.             else Dest.dwSize := sizeof (TRasDialParams);
  316.             StrPCopy (Dest.EntryName, fEntries [fItemIndex]);
  317.             if CallProc (RasGetEntryDialParams (PhoneBookNameAsPChar, Dest, GotPassword)) then Result := Dest.dwSize;
  318.         end;
  319.     end;
  320. end;
  321.  
  322. function TRASPhoneBookManager.GetDialParameters (Index: Integer): String;
  323. var
  324.     GotPassword: Bool;
  325.     Params: TRasDialParamsNT4_2000;
  326. begin
  327.     if InternalGetDialParameters (Params, GotPassword) > 0 then begin
  328.         if not GotPassword then Params.Password := '---not available----';
  329.         case Index of
  330.             0:     Result := Params.UserName;
  331.             1:     Result := Params.Password;
  332.         end;
  333.     end;
  334. end;
  335.  
  336. function TRASPhoneBookManager.InternalGetEntryProperties (var Dest: TRASEntry): Boolean;
  337. var
  338.     EntrySize, DevInfoSize: Integer;
  339.     Buffer: array [0..10000] of Char;
  340.     RasGetEntryProperties: function (Phonebook, EntryName: PChar; var Entry; var EntrySize: Integer;
  341.                                      DevInfo: Pointer; var DevInfoSize: Integer): Integer; stdcall;
  342. begin
  343.     Result := False;
  344.     if fAvailable and (fItemIndex >= 0) then begin
  345.         RasGetEntryProperties := GetProc ('RasGetEntryPropertiesA');
  346.         if Assigned (RasGetEntryProperties) then begin
  347.             PInteger (@Buffer)^ := sizeof (TRASEntry);
  348.             EntrySize := sizeof (Buffer);  DevInfoSize := 0;
  349.             Result := CallProc (RasGetEntryProperties (PhoneBookNameAsPChar, PChar (fEntries [fItemIndex]), Buffer, EntrySize, Nil, DevInfoSize));
  350.             if Result then Move (Buffer, Dest, sizeof (TRASEntry));
  351.         end;
  352.     end;
  353. end;
  354.  
  355. function TRASPhoneBookManager.GetEntryProperties (Index: Integer): String;
  356. var
  357.     Props: TRASEntry;
  358. begin
  359.     if InternalGetEntryProperties (Props) then begin
  360.         case Index of
  361.             0:     Result := Props.LocalPhoneNumber;
  362.             1:     Result := Props.DeviceType;
  363.             2:     Result := Props.DeviceName;
  364.         end;
  365.     end;
  366. end;
  367.  
  368. procedure Register;
  369. begin
  370.     RegisterComponents ('DelphiMag', [TRASPhoneBookManager]);
  371. end;
  372.  
  373. end.
  374.  
  375.     TRASPhoneBookManager = class (TRASBaseComponent)
  376.     private
  377.         { Private declarations }
  378.         fDeviceNames, fDeviceTypes, fDummy2: TStrings;
  379.     protected
  380.         { Protected declarations }
  381.     public
  382.         { Public declarations }
  383.         constructor Create (AOwner: TComponent); override;
  384.         destructor Destroy; override;
  385.         procedure Refresh;
  386.     published
  387.         { Published declarations }
  388.         property DeviceNames: TStrings read fDeviceNames write fDummy2 stored False;
  389.         property DeviceTypes: TStrings read fDeviceTypes write fDummy2 stored False;
  390.     end;
  391.  
  392.  
  393. constructor TRASPhoneBook.Create (AOwner: TComponent);
  394. begin
  395.     Inherited Create (AOwner);
  396.     fDeviceNames := TStringList.Create;
  397.     fDeviceTypes := TStringList.Create;
  398.     Refresh;
  399. end;
  400.  
  401. destructor TRASPhoneBook.Destroy;
  402. begin
  403.     fDeviceNames.Free;
  404.     fDeviceTypes.Free;
  405.     Inherited;
  406. end;
  407.  
  408. procedure TRASPhoneBook.Refresh;
  409. type
  410.     TRasDevInfo = record
  411.     dwSize: DWORD;
  412.     DeviceType: array [0..16] of Char;
  413.     DeviceName: array [0..128] of Char;
  414.     end;
  415. var
  416.     CurEntry: PChar;
  417.     Buffer: array [0..10000] of Char;
  418.     Idx, BufSize, NumDevices, EntrySize: Integer;
  419.     RasEnumDevices: function (Buffer: PChar; var BufSize,
  420.                               NumDevices: Integer): Integer; stdcall;
  421. begin
  422.     if fAvailable then begin
  423.         // First off, refresh the entries list
  424.         fDeviceNames.Clear;
  425.         fDeviceTypes.Clear;
  426.         RasEnumDevices := GetProc ('RasEnumDevicesA');
  427.         EntrySize := sizeof (TRasDevInfo);
  428.         PInteger (@Buffer)^ := EntrySize;  BufSize := sizeof (Buffer);
  429.         RasEnumDevices (Buffer, BufSize, NumDevices);
  430.         CurEntry := Buffer;
  431.         for Idx := 0 to NumDevices - 1 do begin
  432.             fDeviceTypes.Add (CurEntry + sizeof (Integer));
  433.             fDeviceNames.Add (CurEntry + sizeof (Integer) + 17);
  434.             Inc (CurEntry, EntrySize);
  435.         end;
  436.     end;
  437. end;
  438.  
  439.